home *** CD-ROM | disk | FTP | other *** search
- /*
- Half-Life MAP viewing utility.
- Copyright (C) 2003 Ryan Samuel Gregg
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
- #include "stdafx.h"
- #include "Frustum.h"
-
- CFrustum::CFrustum()
- {
- fAspect = 1.0f;
-
- fWidth = 1.0f;
- fHeight = 1.0f;
- }
-
- void CFrustum::CalculateFrustum()
- {
- float proj[16]; // Projection matrix.
- float modl[16]; // Modelview matrix.
- float clip[16]; // Clipping planes.
- float fMagnitude;
-
- glGetFloatv(GL_PROJECTION_MATRIX, proj);
- glGetFloatv(GL_MODELVIEW_MATRIX, modl);
-
- // Combine two matrices to get clipping plane.
- clip[ 0] = modl[ 0] * proj[ 0] + modl[ 1] * proj[ 4] + modl[ 2] * proj[ 8] + modl[ 3] * proj[12];
- clip[ 1] = modl[ 0] * proj[ 1] + modl[ 1] * proj[ 5] + modl[ 2] * proj[ 9] + modl[ 3] * proj[13];
- clip[ 2] = modl[ 0] * proj[ 2] + modl[ 1] * proj[ 6] + modl[ 2] * proj[10] + modl[ 3] * proj[14];
- clip[ 3] = modl[ 0] * proj[ 3] + modl[ 1] * proj[ 7] + modl[ 2] * proj[11] + modl[ 3] * proj[15];
-
- clip[ 4] = modl[ 4] * proj[ 0] + modl[ 5] * proj[ 4] + modl[ 6] * proj[ 8] + modl[ 7] * proj[12];
- clip[ 5] = modl[ 4] * proj[ 1] + modl[ 5] * proj[ 5] + modl[ 6] * proj[ 9] + modl[ 7] * proj[13];
- clip[ 6] = modl[ 4] * proj[ 2] + modl[ 5] * proj[ 6] + modl[ 6] * proj[10] + modl[ 7] * proj[14];
- clip[ 7] = modl[ 4] * proj[ 3] + modl[ 5] * proj[ 7] + modl[ 6] * proj[11] + modl[ 7] * proj[15];
-
- clip[ 8] = modl[ 8] * proj[ 0] + modl[ 9] * proj[ 4] + modl[10] * proj[ 8] + modl[11] * proj[12];
- clip[ 9] = modl[ 8] * proj[ 1] + modl[ 9] * proj[ 5] + modl[10] * proj[ 9] + modl[11] * proj[13];
- clip[10] = modl[ 8] * proj[ 2] + modl[ 9] * proj[ 6] + modl[10] * proj[10] + modl[11] * proj[14];
- clip[11] = modl[ 8] * proj[ 3] + modl[ 9] * proj[ 7] + modl[10] * proj[11] + modl[11] * proj[15];
-
- clip[12] = modl[12] * proj[ 0] + modl[13] * proj[ 4] + modl[14] * proj[ 8] + modl[15] * proj[12];
- clip[13] = modl[12] * proj[ 1] + modl[13] * proj[ 5] + modl[14] * proj[ 9] + modl[15] * proj[13];
- clip[14] = modl[12] * proj[ 2] + modl[13] * proj[ 6] + modl[14] * proj[10] + modl[15] * proj[14];
- clip[15] = modl[12] * proj[ 3] + modl[13] * proj[ 7] + modl[14] * proj[11] + modl[15] * proj[15];
-
- mFrustum[0][0] = clip[ 3] - clip[ 0];
- mFrustum[0][1] = clip[ 7] - clip[ 4];
- mFrustum[0][2] = clip[11] - clip[ 8];
- mFrustum[0][3] = clip[15] - clip[12];
-
- fMagnitude = 1.0f / (float)(Math::Sqrt(mFrustum[0][0] * mFrustum[0][0] + mFrustum[0][1] * mFrustum[0][1] + mFrustum[0][2] * mFrustum[0][2]));
- mFrustum[0][0] *= fMagnitude;
- mFrustum[0][1] *= fMagnitude;
- mFrustum[0][2] *= fMagnitude;
- mFrustum[0][3] *= fMagnitude;
-
- mFrustum[1][0] = clip[ 3] + clip[ 0];
- mFrustum[1][1] = clip[ 7] + clip[ 4];
- mFrustum[1][2] = clip[11] + clip[ 8];
- mFrustum[1][3] = clip[15] + clip[12];
-
- fMagnitude = 1.0f / (float)(Math::Sqrt(mFrustum[1][0] * mFrustum[1][0] + mFrustum[1][1] * mFrustum[1][1] + mFrustum[1][2] * mFrustum[1][2]));
- mFrustum[1][0] *= fMagnitude;
- mFrustum[1][1] *= fMagnitude;
- mFrustum[1][2] *= fMagnitude;
- mFrustum[1][3] *= fMagnitude;
-
- mFrustum[2][0] = clip[ 3] + clip[ 1];
- mFrustum[2][1] = clip[ 7] + clip[ 5];
- mFrustum[2][2] = clip[11] + clip[ 9];
- mFrustum[2][3] = clip[15] + clip[13];
-
- fMagnitude = 1.0f / (float)(Math::Sqrt(mFrustum[2][0] * mFrustum[2][0] + mFrustum[2][1] * mFrustum[2][1] + mFrustum[2][2] * mFrustum[2][2]));
- mFrustum[2][0] *= fMagnitude;
- mFrustum[2][1] *= fMagnitude;
- mFrustum[2][2] *= fMagnitude;
- mFrustum[2][3] *= fMagnitude;
-
- mFrustum[3][0] = clip[ 3] - clip[ 1];
- mFrustum[3][1] = clip[ 7] - clip[ 5];
- mFrustum[3][2] = clip[11] - clip[ 9];
- mFrustum[3][3] = clip[15] - clip[13];
-
- fMagnitude = 1.0f / (float)(Math::Sqrt(mFrustum[3][0] * mFrustum[3][0] + mFrustum[3][1] * mFrustum[3][1] + mFrustum[3][2] * mFrustum[3][2]));
- mFrustum[3][0] *= fMagnitude;
- mFrustum[3][1] *= fMagnitude;
- mFrustum[3][2] *= fMagnitude;
- mFrustum[3][3] *= fMagnitude;
-
- mFrustum[4][0] = clip[ 3] - clip[ 2];
- mFrustum[4][1] = clip[ 7] - clip[ 6];
- mFrustum[4][2] = clip[11] - clip[10];
- mFrustum[4][3] = clip[15] - clip[14];
-
- fMagnitude = 1.0f / (float)(Math::Sqrt(mFrustum[4][0] * mFrustum[4][0] + mFrustum[4][1] * mFrustum[4][1] + mFrustum[4][2] * mFrustum[4][2]));
- mFrustum[4][0] *= fMagnitude;
- mFrustum[4][1] *= fMagnitude;
- mFrustum[4][2] *= fMagnitude;
- mFrustum[4][3] *= fMagnitude;
-
- mFrustum[5][0] = clip[ 3] + clip[ 2];
- mFrustum[5][1] = clip[ 7] + clip[ 6];
- mFrustum[5][2] = clip[11] + clip[10];
- mFrustum[5][3] = clip[15] + clip[14];
-
- fMagnitude = 1.0f / (float)(Math::Sqrt(mFrustum[5][0] * mFrustum[5][0] + mFrustum[5][1] * mFrustum[5][1] + mFrustum[5][2] * mFrustum[5][2]));
- mFrustum[5][0] *= fMagnitude;
- mFrustum[5][1] *= fMagnitude;
- mFrustum[5][2] *= fMagnitude;
- mFrustum[5][3] *= fMagnitude;
- }
-
- bool CFrustum::PointInFrustum(Vertex3f vPoint)
- {
- if (mFrustum[0][0] * vPoint.X + mFrustum[0][1] * vPoint.Y + mFrustum[0][2] * vPoint.Z + mFrustum[0][3] <= 0) { return(true); }
- if (mFrustum[1][0] * vPoint.X + mFrustum[1][1] * vPoint.Y + mFrustum[1][2] * vPoint.Z + mFrustum[1][3] <= 0) { return(true); }
- if (mFrustum[2][0] * vPoint.X + mFrustum[2][1] * vPoint.Y + mFrustum[2][2] * vPoint.Z + mFrustum[2][3] <= 0) { return(true); }
- if (mFrustum[3][0] * vPoint.X + mFrustum[3][1] * vPoint.Y + mFrustum[3][2] * vPoint.Z + mFrustum[3][3] <= 0) { return(true); }
- if (mFrustum[4][0] * vPoint.X + mFrustum[4][1] * vPoint.Y + mFrustum[4][2] * vPoint.Z + mFrustum[4][3] <= 0) { return(true); }
- if (mFrustum[5][0] * vPoint.X + mFrustum[5][1] * vPoint.Y + mFrustum[5][2] * vPoint.Z + mFrustum[5][3] <= 0) { return(true); }
- return false;
- }
-
- bool CFrustum::SphereInFrustum(BoundingSphere Sphere)
- {
- if(mFrustum[0][0] * Sphere.vOrigin.X + mFrustum[0][1] * Sphere.vOrigin.Y + mFrustum[0][2] * Sphere.vOrigin.Z + mFrustum[0][3] <= -Sphere.fRadius) { return(false); }
- if(mFrustum[1][0] * Sphere.vOrigin.X + mFrustum[1][1] * Sphere.vOrigin.Y + mFrustum[1][2] * Sphere.vOrigin.Z + mFrustum[1][3] <= -Sphere.fRadius) { return(false); }
- if(mFrustum[2][0] * Sphere.vOrigin.X + mFrustum[2][1] * Sphere.vOrigin.Y + mFrustum[2][2] * Sphere.vOrigin.Z + mFrustum[2][3] <= -Sphere.fRadius) { return(false); }
- if(mFrustum[3][0] * Sphere.vOrigin.X + mFrustum[3][1] * Sphere.vOrigin.Y + mFrustum[3][2] * Sphere.vOrigin.Z + mFrustum[3][3] <= -Sphere.fRadius) { return(false); }
- if(mFrustum[4][0] * Sphere.vOrigin.X + mFrustum[4][1] * Sphere.vOrigin.Y + mFrustum[4][2] * Sphere.vOrigin.Z + mFrustum[4][3] <= -Sphere.fRadius) { return(false); }
- if(mFrustum[5][0] * Sphere.vOrigin.X + mFrustum[5][1] * Sphere.vOrigin.Y + mFrustum[5][2] * Sphere.vOrigin.Z + mFrustum[5][3] <= -Sphere.fRadius) { return(false); }
- return true;
- }
-
- bool CFrustum::CubeInFrustum(BoundingBox Box)
- {
- for(int i = 0; i < 6; i++)
- {
- if(mFrustum[i][0] * Box.vNegBound.X + mFrustum[i][1] * Box.vNegBound.Y + mFrustum[i][2] * Box.vNegBound.Z + mFrustum[i][3] > 0) { continue; }
- if(mFrustum[i][0] * Box.vPosBound.X + mFrustum[i][1] * Box.vNegBound.Y + mFrustum[i][2] * Box.vNegBound.Z + mFrustum[i][3] > 0) { continue; }
- if(mFrustum[i][0] * Box.vNegBound.X + mFrustum[i][1] * Box.vPosBound.Y + mFrustum[i][2] * Box.vNegBound.Z + mFrustum[i][3] > 0) { continue; }
- if(mFrustum[i][0] * Box.vPosBound.X + mFrustum[i][1] * Box.vPosBound.Y + mFrustum[i][2] * Box.vNegBound.Z + mFrustum[i][3] > 0) { continue; }
- if(mFrustum[i][0] * Box.vNegBound.X + mFrustum[i][1] * Box.vNegBound.Y + mFrustum[i][2] * Box.vPosBound.Z + mFrustum[i][3] > 0) { continue; }
- if(mFrustum[i][0] * Box.vPosBound.X + mFrustum[i][1] * Box.vNegBound.Y + mFrustum[i][2] * Box.vPosBound.Z + mFrustum[i][3] > 0) { continue; }
- if(mFrustum[i][0] * Box.vNegBound.X + mFrustum[i][1] * Box.vPosBound.Y + mFrustum[i][2] * Box.vPosBound.Z + mFrustum[i][3] > 0) { continue; }
- if(mFrustum[i][0] * Box.vPosBound.X + mFrustum[i][1] * Box.vPosBound.Y + mFrustum[i][2] * Box.vPosBound.Z + mFrustum[i][3] > 0) { continue; }
- return false;
- }
- return true;
- }